package com.example.his.api.front.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import com.example.his.api.common.R;
import com.example.his.api.config.sa_token.StpCustomerUtil;
import com.example.his.api.front.form.LoginForm;
import com.example.his.api.front.form.SendSmsCodeForm;
import com.example.his.api.front.form.UpdateCustomerForm;
import com.example.his.api.front.service.CustomerService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping ( "/front/customer" )
public class CustomerController {

  @Resource
  private CustomerService customerService;

  /**
   * 发送短信验证码接口
   *
   * @param form 包含手机号的表单对象，需符合手机号格式验证
   * @return 返回操作结果信息及是否发送成功布尔值
   */
  @PostMapping ( "/sendSmsCode" )
  public R sendSmsCode( @Valid @RequestBody SendSmsCodeForm form ) {
    // 调用服务层发送短信验证码
    boolean bool = customerService.sendSmsCode( form.getTel() );

    // 根据发送结果设置返回消息
    String msg = bool ? "短信验证码已发送" : "无法发送短信验证码";

    // 构造并返回统一响应结果
    return R.ok( msg ).put( "bool", bool );
  }

  /**
   * 客户登录接口
   *
   * @param form 登录表单对象，包含手机号和验证码
   * @return 登录结果及令牌信息
   */
  @PostMapping ( "/login" )
  public R login( @Valid @RequestBody LoginForm form ) {
    // 调用服务层进行登录验证
    HashMap map = customerService.login( form.getTel(), form.getCode() );

    // 获取登录结果和消息
    Boolean result = MapUtil.getBool( map, "result" );
    String msg = MapUtil.getStr( map, "msg" );

    // 构建基础响应对象
    R r = R.ok( msg ).put( "result", result );

    // 如果登录成功，生成并返回令牌
    if ( result ) {
      // 获取用户ID
      Integer id = MapUtil.getInt( map, "id" );

      // 执行登录操作，生成会话
      StpCustomerUtil.login( id );

      // 获取生成的令牌
      String token = StpCustomerUtil.getTokenValue();

      // 将令牌添加到响应中
      r.put( "token", token );
    }

    return r;
  }

  /**
   * 客户退出登录接口
   *
   * @return 退出结果信息
   */
  @GetMapping ( "/logout" )
  @SaCheckLogin ( type = StpCustomerUtil.TYPE )
  public R logout() {
    // 获取当前登录的客户ID
    int id = StpCustomerUtil.getLoginIdAsInt();
    // 执行退出登录操作，指定设备类型为Web
    StpCustomerUtil.logout( id, "Web" );

    // 返回退出成功的消息
    return R.ok().put( "msg", "退出登录成功" );
  }

  /**
   * 检查客户是否已登录
   *
   * @return 返回检查结果，true表示已登录，false表示未登录
   */
  @GetMapping ( "/checkLogin" )
  public R checkLogin() {
    // 调用Sa-Token工具类检查当前会话是否已登录
    boolean bool = StpCustomerUtil.isLogin();
    // 构造并返回统一响应结果
    return R.ok().put( "result", bool );
  }

  /**
   * 查询客户个人信息摘要
   *
   * @return 包含客户个人信息的HashMap结果
   */
  @GetMapping ( "/searchSummary" )
  @SaCheckLogin ( type = StpCustomerUtil.TYPE )
  public R searchSummary() {
    // 获取当前登录客户的ID
    int id = StpCustomerUtil.getLoginIdAsInt();
    // 调用服务层查询客户摘要信息
    HashMap map = customerService.searchSummary( id );
    // 返回查询结果
    return R.ok().put( "result", map );
  }

  /**
   * 更新客户个人信息接口
   *
   * @param form 包含客户更新信息的表单对象，需通过验证
   * @return 更新结果，true表示更新成功，false表示更新失败
   */
  @PostMapping ( "/update" )
  @SaCheckLogin ( type = StpCustomerUtil.TYPE )
  public R update( @Valid @RequestBody UpdateCustomerForm form ) {
    // 获取当前登录客户的ID
    int id = StpCustomerUtil.getLoginIdAsInt();
    // 将表单对象转换为Map，并添加客户ID
    Map < String, Object > param = BeanUtil.beanToMap( form );
    param.put( "id", id );
    // 调用服务层更新客户信息
    boolean bool = customerService.update( param );
    // 返回更新结果
    return R.ok().put( "result", bool );
  }

}
